﻿using System;
using System.Collections;
using System.Timers;

using OptimalisationFramework.Interfaces;
using OptimalisationFramework.Utilities;

namespace OptimalisationFramework.Metaheuritics
{
    class TabuSearch : AbstractTimer,IMetaHeuristic
    {
        private ITrajectorySearch sol;
        private ArrayList tabuList;

        // threaded lock situation
        private object locker;



        public TabuSearch(ITrajectorySearch sol)
        {
            this.sol = sol;
            tabuList = new ArrayList();
            locker = new object();
        }

        public TabuSearch(ITrajectorySearch sol, uint seconds)
        {
            this.sol = sol;
            tabuList = new ArrayList();
            locker = new object();
            SetTime(seconds);
        }

        public ITrajectorySearch GetSolution()
        {
            return sol;
        }
        public void Start()
        {
            if (tm != null)
            {
                StartTimer();
            }
            Solve();
        }

        public void Stop()
        {
            stopProcess = true;
        }

        public void Solve()
        {
            sol = sol.GenerateInitialSolution();
            while (!sol.StopSearch() && !stopProcess)
            {
                // find a better neighbourgh solution
                ITrajectorySearch sTemp = sol.AdjustSolution();                
                if(!tabuList.Contains(sTemp.ObjectifFunction()))
                {
                   // lock (locker) {
                        tabuList.Add(sTemp.ObjectifFunction());
                        if (sTemp.ObjectifFunction() > sol.ObjectifFunction())
                        {                            
                            sol = sTemp;
                        }
                  //  }
                }                
            }
            if(tm!=null) 
                StopTimer();                      
        }
    }

}
